#ifndef IGSLIB_DISPENSER_H
#define IGSLIB_DISPENSER_H

#include <set>
#include <vector>
#include "igslib_idispenser.h"

namespace igslib 
{
	class CDispenser:virtual public IDispenser
	{
        protected:
            float nval;
            ErrorState es;
            ISpi* spi;
            IGPIO* gpio_in;
			IGPIO* gpio_mc;
			IGPIO* gpio_mcc;
            std::set<IDispenserEvent*> events;
            std::pair<float,float> confirm;
            float jt; // jammed time
            float et; // empty time
            bool ha; // high active
            bool eec; // Enable Error Check
            State state;
        public:
            CDispenser()
            {
                state = State::idle;
                nval = 0;
                spi = nullptr;
                gpio_in = nullptr;
				gpio_mc = nullptr;
				gpio_mcc = nullptr;
                confirm = std::make_pair(14,500);
                jt = 160;
                et = 500;
                ha = false;
                eec = true;
                ClearError();
            }
            virtual float GetValue() { return nval; }
            virtual void SetValue(const float& value) { nval = value; }
            virtual void AddValue(const float& value) { nval += value; }
            virtual ErrorState GetErrorState() { return es; }
            virtual void SetErrorCheck(const bool& value) { eec = value; }
            virtual bool GetErrorCheck() { return eec; }
            virtual void ClearError() { es = ErrorState::none; }
            virtual void SetEventHandler(IDispenserEvent* value) { events.insert(value); }
            virtual void Update() { }
            virtual void Run() { }
            virtual void Stop() { }
            virtual void AbortDispension() { }
            virtual void PrizeOut() { }
            virtual void Reset() { }
            virtual void SetConfirmRange(const float& min,const float& max) { confirm = std::make_pair(min,max); }
            virtual void SetJammedTime(const float& value) { jt = value; }
            virtual void SetEmptyTime(const float& value) { et = value; }
            virtual void SetHighActive(const bool& value) { ha = value; }
            virtual State GetState() { return state; }
            virtual void SetSPI(ISpi* value) { spi = value; }
            virtual void SetGPIO(IGPIO* value,IGPIO* value1, IGPIO* value2)  { gpio_in = value; gpio_mc = value1; gpio_mcc = value1;}
	};

    class CHopper:public CDispenser,public IHopper
    {
        protected:
            RunMode mode;
            float et[3]; // empty time
        public:
            CHopper()
            {
                mode = RunMode::none;
            }
            RunMode GetCustomRunMode() { return mode; }
            void JamRecovery() { }
            void CustomRun(RunMode) { }

            virtual void SetEmptyTime(const float& value,const float& value1,const float& value2)
            {
                et[0] = value;
                et[1] = value1;
                et[2] = value2;
            }
    };

    class CDispenserManager:public IDispenserManager
    {
        static IDispenserManager* instance;
        public:
            static IDispenserManager* GetInstance();
			virtual IHopper* New_ProjMCU(const std::string&);
    };
};

#endif
